const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const express = require('express');
const session = require('express-session')
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const RedisStore = require('connect-redis')(session)
const redis = require('redis')
const csurf = require('csurf')
const api = require('./servers/api')
const app = express();

// Import and Set Nuxt.js options
const config = require('./nuxt.config.js')
config.dev = process.env.NODE_ENV === 'development'

async function start() {
  // Instantiate nuxt.js
  //app.use(api.routes(), api.allowedMethods())

  const nuxt = new Nuxt(config)

  const {
    host = process.env.HOST || '127.0.0.1',
    port = process.env.PORT || 3000
  } = nuxt.options.server

  // Build in development
  if (config.dev) {
    app.use((req, res, next) => {
      res.header("Access-Control-Allow-Origin", "http://localhost:8080");
      res.header("Access-Control-Allow-Headers", 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With, x-token, _csrf, x-csrf-token');
      res.header("Access-Control-Allow-Credentials", "true");
      res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
      if (req.method.toLowerCase() == 'options') {
        res.sendStatus(200);  // 让options尝试请求快速结束
      } else {
        next();
      }
    })
    const builder = new Builder(nuxt)
    await builder.build()
  } else {
    await nuxt.ready()
  }

  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: true }));
  app.use(cookieParser());
  if (process.env.NODE_ENV === 'production') {
    app.use(csurf({ cookie: true })) //, ignoreMethods:['HEAD', 'OPTIONS']
    app.use(function (err, req, res, next) {
      res.cookie('X-CSRF-TOKEN', req.csrfToken())
      if (err.code !== 'EBADCSRFTOKEN') return next(err)
      res.send('form tampered with')
    })
  }
  app.use(session({
    "secret": 'tuyibouy345#$#@~8#$:',
    "cookie": { httpOnly: true, maxAge: 1000 * 60 * 60 }, // * 24 * 1
    "resave": true,
    "saveUninitialized": false,
    "store": new RedisStore({
      client: redis.createClient(process.env.REDIS_PORT, process.env.REDIS_HOST)
    })
  }));
  app.use(api)
  app.use(nuxt.render)
  app.listen(port, host)

  consola.ready({
    message: `Server listening on http://${host}:${port}`,
    badge: true
  })
}

start()
